package gameLogic

import (
	"net"
	"google.golang.org/protobuf/proto"
	// "server_cluster/battle/db"
	//"server_cluster/common/myepoll"
	// "server_cluster/common/tools"
	"server_cluster/battle/sharemem"
	"server_cluster/common/config"
	"server_cluster/common/logger"
	"server_cluster/common/mysock"
	"server_cluster/common/protoc/pb"
)

func ShmUserCheck() {
	//	return
	var myshm = sharemem.Myshm
	user_map := sharemem.GetShmUserMap()
	for _, v := range user_map {
		if myshm.Time_now > v.GetKillTime() {
			v.Clean_user()
		}
	}
}

func BattleCreate(conn net.Conn, mybuf *mysock.SockBuf, fd int32) {
	// 获取LOGIC数据
	createreq := pb.SS_Create_Battle{}
	err := proto.Unmarshal(mybuf.Data[mysock.HEAD_LEN:mysock.HEAD_LEN+mybuf.Data_length], &createreq)
	if err != nil {
		logger.Error("parse Fight create error:%v", err)
		mybuf.Code = config.PROTO
		mybuf.WriteToByConn(conn, nil)
		return
	}
	uid := int64(mybuf.Session)
	user_fight_data := createreq.GetServerData()
	is_reset := createreq.GetIsReset()
	active_fight := createreq.GetActiveFight()
	// logger.Info("uid=%d token=%s,err=%v",uid,token,nerr)
	// logger.Info("fight_data = %v",fight_data)
	// 本机查询缓存是否还在
	shm_user := sharemem.GetShmUserByUid(uid)
	if shm_user != nil {
		// 缓存还在
		/*
		shm_fd := shm_user.GetFd()
		// 先断开老连接old_fd
		if shm_fd > 0 && fd != shm_fd {
			conns := myepoll.Eps.GetConnByFd(shm_fd)
			if conns != nil {
				conns.Socket.Close()
				myepoll.Eps.Fds.Delete(shm_fd)
			}
		}*/
		shm_user.SetFd(fd)
		// 直接使用
//		logger.Info("get data from sharemem")
	} else {
		// new共享内存user
		shm_user = sharemem.Get_user_by_id(uid, fd)
	}
	if shm_user == nil {
		mybuf.Code = config.FULL
		mybuf.WriteToByConn(conn, nil)
		return
	}
	//logger.Info("create fight index = %d", shm_user.GetIndex())
	// 创建战斗
	(*shm_user).DeleteShmUserAllMap()
	mybuf.Code = (*shm_user).CreateFight(user_fight_data)
	(*shm_user).SetKillTime()
	if mybuf.Code != config.OK {
		// 创建战斗失败
		// 清理
		logger.Warn("user %d create battle error",(*shm_user).GetId())
		shm_user.Clean_user()
		mybuf.WriteToByConn(conn, nil)
		return
	}
	//
	u := &pb.SC_Create_Battle{
		Battle: user_fight_data,
		IsReset:is_reset,
		ActiveFight:active_fight,
	}
	// 返回消息
	// logger.Info("create %v",u)
	logger.Warn("user %d create battle_group_id = %d",(*shm_user).GetId(),(*shm_user).GetBGId())
	data, _ := proto.Marshal(u)
	mybuf.WriteToByConn(conn, data)
}

func BattleAction(conn net.Conn, mybuf *mysock.SockBuf, shm_user *sharemem.ShmUser) {
	// 获取数据
	req := pb.CS_Battle_Action{}
	err := proto.Unmarshal(mybuf.Data[mysock.HEAD_LEN:mysock.HEAD_LEN+mybuf.Data_length], &req)
	if err != nil {
		logger.Error("parse Fight action error:%v", err)
		mybuf.Code = config.PROTO
		mybuf.WriteToByConn(conn, nil)
		return
	}

	if !shm_user.CheckActionNum() {
		logger.Error("fight action num is over limit! uid=%d",shm_user.GetId())
		mybuf.Code = config.BATTLE_ACTION_ERROR
		mybuf.WriteToByConn(conn,nil)
		return
	}

	id := req.GetId()
	root_time := req.GetRootTime()
	node_time := req.GetNodeTime()
	trigger_type := int8(req.GetTriggerType())
	trigger := int8(req.GetTriggerIndex())
	target_type := int8(req.GetTargetType())
	target := int8(req.GetTargetIndex())
	card := req.GetCard()
	num := int8(req.GetNum())

	//logger.Info("id:%v root_time:%v node_time:%v trigger_type:%v trigger:%v target_type:%v target:%v card:%v num:%v",id,root_time,node_time,trigger_type,trigger,target_type,target,card,num)
	if !shm_user.ActionParamCheck(id,root_time,node_time,trigger_type,trigger,target_type,target,card,num) {
		mybuf.Code = config.BATTLE_ACTION_PARAM
	} else {
		shm_user.SetAction(id,root_time,node_time,trigger_type,trigger,target_type,target,card,num)
		mybuf.Code = config.OK
	}
	data,_ := proto.Marshal(&req)
	mybuf.WriteToByConn(conn,data)
}

func BattleOver(conn net.Conn, mybuf *mysock.SockBuf, shm_user *sharemem.ShmUser) {
	req := pb.CS_Battle_Over{}
	err := proto.Unmarshal(mybuf.Data[mysock.HEAD_LEN:mysock.HEAD_LEN+mybuf.Data_length], &req)
	if err != nil {
		logger.Error("parse Fight action error:%v", err)
		mybuf.Code = config.PROTO
		mybuf.WriteToByConn(conn, nil)
		return
	}
	mybuf.Code = config.OK
	res := pb.SS_Battle_Over{}
	res.Battle = &pb.ServerUserFightData{
		BattleGroupId:shm_user.GetBattleGroupId(),
	}
	status := req.GetStatus()
	//test
	//shm_user.BattleCheck(res.Battle)
	//
	/*
	if status {
		//战斗胜利校验
		if status != shm_user.BattleCheck(res.Battle) {
			//前后端校验不一致，可能作弊！！！
			mybuf.Code = config.BATTLE_OVER_ERROR
			status = false
		}
	}*/
	res.Status = status
	data,_ := proto.Marshal(&res)
	mybuf.WriteToByConn(conn,data)
	shm_user.Clean_user()
}
